package net.hn.hnms.biz.safety.config;

import com.alibaba.druid.pool.DruidDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Map;

/**
 * 智呈物联 pan'sx
 * 2022/7/30 17:33
 * 1.0 version
 */
@Slf4j
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "vehicleEntityManagerFactory",
        transactionManagerRef = "vehicleTransactionManager",
        //所有访问此数据源的repository的 package位置
        basePackages = {
                "net.hn.hnms.biz.safety.vehicle"
        })
public class VehicleConfig {

    @Autowired
    private JpaProperties jpaProperties;
    @Autowired
    private HibernateProperties hibernateProperties;

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.vehicle")
    public DruidProperties vehicleDataSourceProperties() {
        return new DruidProperties();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.vehicle.filter")
    public DruidFilterProperties vehicleDataSourceFilter() {
        return new DruidFilterProperties();
    }


    @Bean(name = "vehicleDataSource")
    public DataSource vehicleDataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        DruidProperties  druidProperties = vehicleDataSourceProperties();
        druidDataSource.setUrl(druidProperties.getUrl());
        druidDataSource.setUsername(druidProperties.getUsername());
        druidDataSource.setPassword(druidProperties.getPassword());
        druidDataSource.setDriverClassName(druidProperties.getDriverClassName());

        druidDataSource.setInitialSize(druidProperties.getInitialSize());
        druidDataSource.setMinIdle(druidProperties.getMinIdle());
        druidDataSource.setMaxActive(druidProperties.getMaxActive());
        druidDataSource.setMaxWait(druidProperties.getMaxWait());
        druidDataSource.setTimeBetweenEvictionRunsMillis(druidProperties.getTimeBetweenEvictionRunsMillis());
        druidDataSource.setMinEvictableIdleTimeMillis(druidProperties.getMinEvictableIdleTimeMillis());
        druidDataSource.setValidationQuery(druidProperties.getValidationQuery());

        druidDataSource.setTestWhileIdle(druidProperties.getTestWhileIdle());
        druidDataSource.setTestOnBorrow(druidProperties.getTestOnBorrow());
        druidDataSource.setTestOnReturn(druidProperties.getTestOnReturn());
        druidDataSource.setBreakAfterAcquireFailure(true);
        druidDataSource.setConnectionErrorRetryAttempts(0);

        // 此处动态添加Filter
        final DruidFilterProperties druidFilterProperties = vehicleDataSourceFilter();
        try {
            druidDataSource.setProxyFilters(druidFilterProperties.getFilters());
            druidDataSource.init();
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        }

        return druidDataSource;
    }

    @Bean(name = "vehicleEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean vehicleEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        // 此数据源强制不用JPA检查表结构
        hibernateProperties.setDdlAuto("update");
        Map<String, Object> properties = hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(),
                new HibernateSettings());
//        properties.put("hibernate.physical_naming_strategy","org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl");
//        properties.put("hibernate.dialect","org.hibernate.dialect.MySQL5Dialect");
        //所有用到主数据源的实体的包位置
        return builder.dataSource(vehicleDataSource()).properties(properties).
                packages("net.hn.hnms.biz.safety.vehicle").persistenceUnit("vehicle").build();
    }

    @Bean(name = "vehicleTransactionManager")
    public PlatformTransactionManager vehicleTransactionManager(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(vehicleEntityManagerFactory(builder).getObject());
    }
    @Bean(name = "vehicleEntityManager")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder){
        return vehicleEntityManagerFactory(builder).getObject().createEntityManager();
    }
    @Bean(name = "vehicleJdbcTemplate")
    public JdbcTemplate vehicleJdbcTemplate() {
        return new JdbcTemplate(vehicleDataSource());
    }
}
